﻿// -------------------------------------------------------------------------
//    @FileName         :    TestNFShmHashMapWithListAdvanced.h
//    @Author           :    gaoyi
//    @Date             :    2024-01-20
//    @Email			:    445267987@qq.com
//    @Module           :    TestNFShmHashMapWithListAdvanced
//
// -------------------------------------------------------------------------

#pragma once

#include "NFComm/NFShmStl/NFShmHashMapWithList.h"
#include <gtest/gtest.h>
#include <string>
#include <vector>
#include <algorithm>
#include <chrono>
#include <random>

/**
 * @file TestNFShmHashMapWithListAdvanced.h
 * @brief NFShmHashMapWithList 高级链表排序接口的单元测试
 * 
 * 本文件专门测试以下高级接口：
 * 1. insert_list_sorted() - 按有序位置插入元素
 * 2. emplace_list_sorted() - 原地构造并按有序位置插入
 * 3. emplace_hint_list_sorted() - 带提示的原地构造并按有序位置插入
 * 4. move_to_list_node_front() - 将节点移到链表前端
 * 5. move_to_list_node_back() - 将节点移到链表后端
 * 6. move_to_list_sorted() - 将节点移到正确的有序位置
 * 
 * 测试覆盖范围：
 * - 基础功能测试
 * - 自定义比较器测试
 * - 边界情况测试
 * - 性能测试
 * - 与现有接口的兼容性测试
 */

// 测试用的复杂对象类型
struct ProductInfo
{
    int id;
    std::string name;
    double price;
    int category;

    ProductInfo() : id(0), price(0.0), category(0)
    {
    }

    ProductInfo(int i, const std::string& n, double p, int c) : id(i), name(n), price(p), category(c)
    {
    }

    bool operator==(const ProductInfo& other) const
    {
        return id == other.id && name == other.name && price == other.price && category == other.category;
    }

    bool operator<(const ProductInfo& other) const
    {
        if (price != other.price)
            return price < other.price;
        if (category != other.category)
            return category < other.category;
        return id < other.id;
    }
};

/**
 * @brief 测试insert_list_sorted接口：按有序位置插入元素
 */
TEST(NFShmHashMapWithListAdvancedTest, InsertListSorted)
{
    printf("========== InsertListSorted Test ==========\n");

    NFShmHashMapWithList<std::string, int, 100> scoreMap;
    scoreMap.CreateInit();

    // 测试1：使用默认比较器（按value升序）
    printf("Test 1: Default comparator (ascending by value)\n");

    auto result1 = scoreMap.insert_list_sorted({"Charlie", 85});
    EXPECT_TRUE(result1.second); // 新插入成功
    EXPECT_EQ(result1.first->first, "Charlie");
    EXPECT_EQ(result1.first->second, 85);

    auto result2 = scoreMap.insert_list_sorted({"Alice", 92});
    EXPECT_TRUE(result2.second); // 新插入成功

    auto result3 = scoreMap.insert_list_sorted({"Bob", 78});
    EXPECT_TRUE(result3.second); // 新插入成功

    auto result4 = scoreMap.insert_list_sorted({"David", 91});
    EXPECT_TRUE(result4.second); // 新插入成功

    // 尝试插入重复键
    auto result5 = scoreMap.insert_list_sorted({"Alice", 88});
    EXPECT_FALSE(result5.second); // 重复键，插入失败
    EXPECT_EQ(result5.first->second, 92); // 保持原值

    printf("After insert_list_sorted (should be sorted by value):\n");
    std::vector<int> values;
    for (auto it = scoreMap.list_begin(); it != scoreMap.list_end(); ++it)
    {
        printf("  %s: %d\n", it->first.c_str(), it->second);
        values.push_back(it->second);
    }

    // 验证按value升序排列
    EXPECT_TRUE(std::is_sorted(values.begin(), values.end()));
    std::vector<int> expected_values = {78, 85, 91, 92};
    EXPECT_EQ(values, expected_values);

    scoreMap.clear();

    // 测试2：使用自定义比较器（按value降序）
    printf("\nTest 2: Custom comparator (descending by value)\n");

    auto comp = [](const int& a, const int& b) { return a > b; };

    scoreMap.insert_list_sorted({"Charlie", 85}, comp);
    scoreMap.insert_list_sorted({"Alice", 92}, comp);
    scoreMap.insert_list_sorted({"Bob", 78}, comp);
    scoreMap.insert_list_sorted({"David", 91}, comp);

    printf("After insert_list_sorted with descending comparator:\n");
    std::vector<int> desc_values;
    for (auto it = scoreMap.list_begin(); it != scoreMap.list_end(); ++it)
    {
        printf("  %s: %d\n", it->first.c_str(), it->second);
        desc_values.push_back(it->second);
    }

    // 验证按value降序排列
    EXPECT_TRUE(std::is_sorted(desc_values.begin(), desc_values.end(), std::greater<int>()));
    std::vector<int> expected_desc_values = {92, 91, 85, 78};
    EXPECT_EQ(desc_values, expected_desc_values);

    printf("InsertListSorted test passed\n");
}

/**
 * @brief 测试emplace_list_sorted接口：原地构造并按有序位置插入
 */
TEST(NFShmHashMapWithListAdvancedTest, EmplaceListSorted)
{
    printf("========== EmplaceListSorted Test ==========\n");

    NFShmHashMapWithList<int, ProductInfo, 100> productMap;
    productMap.CreateInit();

    // 测试1：使用默认比较器（按ProductInfo的价格升序）
    printf("Test 1: Default comparator (ascending by ProductInfo.price)\n");

    auto result1 = productMap.emplace_list_sorted(1001, ProductInfo(1001, "Laptop", 1200.0, 1));
    EXPECT_TRUE(result1.second);

    auto result2 = productMap.emplace_list_sorted(1002, ProductInfo(1002, "Mouse", 25.0, 2));
    EXPECT_TRUE(result2.second);

    auto result3 = productMap.emplace_list_sorted(1003, ProductInfo(1003, "Keyboard", 80.0, 2));
    EXPECT_TRUE(result3.second);

    auto result4 = productMap.emplace_list_sorted(1004, ProductInfo(1004, "Monitor", 350.0, 3));
    EXPECT_TRUE(result4.second);

    // 尝试插入重复键
    auto result5 = productMap.emplace_list_sorted(1001, ProductInfo(1001, "Gaming Laptop", 1800.0, 1));
    EXPECT_FALSE(result5.second); // 重复键，插入失败

    printf("After emplace_list_sorted (should be sorted by price):\n");
    std::vector<double> prices;
    for (auto it = productMap.list_begin(); it != productMap.list_end(); ++it)
    {
        printf("  ID:%d %s $%.2f (Category:%d)\n", it->first, it->second.name.c_str(), it->second.price, it->second.category);
        prices.push_back(it->second.price);
    }

    // 验证按价格升序排列
    EXPECT_TRUE(std::is_sorted(prices.begin(), prices.end()));
    std::vector<double> expected_prices = {25.0, 80.0, 350.0, 1200.0};
    EXPECT_EQ(prices, expected_prices);

    productMap.clear();

    // 测试2：使用自定义比较器（按类别升序，类别相同按价格降序）
    printf("\nTest 2: Custom comparator (by category asc, then price desc)\n");

    auto comp = [](const ProductInfo& a, const ProductInfo& b)
    {
        if (a.category != b.category)
            return a.category < b.category;
        return a.price > b.price;
    };

    productMap.emplace_list_sorted_comp(comp, 1001, ProductInfo(1001, "Gaming Laptop", 1800.0, 1));
    productMap.emplace_list_sorted_comp(comp, 1002, ProductInfo(1002, "Office Laptop", 1200.0, 1));
    productMap.emplace_list_sorted_comp(comp, 1003, ProductInfo(1003, "Wireless Mouse", 45.0, 2));
    productMap.emplace_list_sorted_comp(comp, 1004, ProductInfo(1004, "Wired Mouse", 25.0, 2));
    productMap.emplace_list_sorted_comp(comp, 1005, ProductInfo(1005, "Gaming Keyboard", 120.0, 2));

    printf("After emplace_list_sorted with custom comparator:\n");
    for (auto it = productMap.list_begin(); it != productMap.list_end(); ++it)
    {
        printf("  ID:%d %s $%.2f (Category:%d)\n", it->first, it->second.name.c_str(), it->second.price, it->second.category);
    }

    // 验证排序正确性
    std::vector<std::pair<int, double>> category_price_pairs;
    for (auto it = productMap.list_begin(); it != productMap.list_end(); ++it)
    {
        category_price_pairs.emplace_back(it->second.category, it->second.price);
    }

    // 验证分类排序和价格排序
    for (size_t i = 1; i < category_price_pairs.size(); ++i)
    {
        auto& prev = category_price_pairs[i - 1];
        auto& curr = category_price_pairs[i];

        bool valid_order = (curr.first > prev.first) || (curr.first == prev.first && curr.second <= prev.second);
        EXPECT_TRUE(valid_order);
    }

    printf("EmplaceListSorted test passed\n");
}

/**
 * @brief 测试emplace_hint_list_sorted接口：带提示的原地构造并按有序位置插入
 */
TEST(NFShmHashMapWithListAdvancedTest, EmplaceHintListSorted)
{
    printf("========== EmplaceHintListSorted Test ==========\n");

    NFShmHashMapWithList<std::string, int, 100> gradeMap;
    gradeMap.CreateInit();

    // 测试：emplace_hint_list_sorted应该忽略hint参数，正确排序
    printf("Test: emplace_hint_list_sorted should maintain sorted order\n");

    auto it1 = gradeMap.emplace_hint_list_sorted("Math", 85);
    EXPECT_EQ(it1->first, "Math");
    EXPECT_EQ(it1->second, 85);

    auto it2 = gradeMap.emplace_hint_list_sorted("Physics", 92);
    EXPECT_EQ(it2->first, "Physics");
    EXPECT_EQ(it2->second, 92);

    auto it3 = gradeMap.emplace_hint_list_sorted("Chemistry", 78);
    EXPECT_EQ(it3->first, "Chemistry");
    EXPECT_EQ(it3->second, 78);

    auto it4 = gradeMap.emplace_hint_list_sorted("Biology", 89);
    EXPECT_EQ(it4->first, "Biology");
    EXPECT_EQ(it4->second, 89);

    printf("After emplace_hint_list_sorted:\n");
    std::vector<int> grades;
    for (auto it = gradeMap.list_begin(); it != gradeMap.list_end(); ++it)
    {
        printf("  %s: %d\n", it->first.c_str(), it->second);
        grades.push_back(it->second);
    }

    // 验证按grade升序排列
    EXPECT_TRUE(std::is_sorted(grades.begin(), grades.end()));
    std::vector<int> expected_grades = {78, 85, 89, 92};
    EXPECT_EQ(grades, expected_grades);

    // 测试带自定义比较器的版本
    gradeMap.clear();

    auto comp = [](const int& a, const int& b) { return a > b; };

    gradeMap.emplace_hint_list_sorted_comp(comp, "Math", 85);
    gradeMap.emplace_hint_list_sorted_comp(comp, "Physics", 92);
    gradeMap.emplace_hint_list_sorted_comp(comp, "Chemistry", 78);
    gradeMap.emplace_hint_list_sorted_comp(comp, "Biology", 89);

    printf("\nAfter emplace_hint_list_sorted with descending comparator:\n");
    std::vector<int> desc_grades;
    for (auto it = gradeMap.list_begin(); it != gradeMap.list_end(); ++it)
    {
        printf("  %s: %d\n", it->first.c_str(), it->second);
        desc_grades.push_back(it->second);
    }

    // 验证按grade降序排列
    EXPECT_TRUE(std::is_sorted(desc_grades.begin(), desc_grades.end(), std::greater<int>()));
    std::vector<int> expected_desc_grades = {92, 89, 85, 78};
    EXPECT_EQ(desc_grades, expected_desc_grades);

    printf("EmplaceHintListSorted test passed\n");
}

/**
 * @brief 综合测试：边界情况和性能测试
 */
TEST(NFShmHashMapWithListAdvancedTest, EdgeCasesAndPerformance)
{
    printf("========== EdgeCasesAndPerformance Test ==========\n");

    // 测试1：空容器的边界情况
    printf("Test 1: Empty container edge cases\n");
    {
        NFShmHashMapWithList<int, int, 10> emptyMap;
        emptyMap.CreateInit();

        // 空容器上的insert_list_sorted
        auto result = emptyMap.insert_list_sorted({1, 100});
        EXPECT_TRUE(result.second);
        EXPECT_EQ(emptyMap.size(), 1);
        EXPECT_EQ(result.first->second, 100);

        emptyMap.clear();
    }

    // 测试2：单元素容器
    printf("Test 2: Single element container\n");
    {
        NFShmHashMapWithList<std::string, int, 10> singleMap;
        singleMap.CreateInit();

        singleMap.insert_list_sorted({"Only", 42});

        auto it = singleMap.find("Only");
        singleMap.move_to_list_node_front(it);
        EXPECT_EQ(singleMap.size(), 1);
        EXPECT_EQ(singleMap.list_begin()->second, 42);

        singleMap.move_to_list_node_back(it);
        EXPECT_EQ(singleMap.size(), 1);
        EXPECT_EQ(singleMap.list_begin()->second, 42);
    }

    // 测试3：性能测试
    printf("Test 3: Performance test with 100 elements\n");
    {
        const int TEST_SIZE = 100;
        NFShmHashMapWithList<int, int, TEST_SIZE> perfMap;
        perfMap.CreateInit();

        // 准备随机数据
        std::vector<int> values;
        for (int i = 1; i <= TEST_SIZE; ++i)
        {
            values.push_back(i * 10);
        }

        std::random_device rd;
        std::mt19937 gen(rd());
        std::shuffle(values.begin(), values.end(), gen);

        // 测试insert_list_sorted性能
        auto start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < TEST_SIZE; ++i)
        {
            perfMap.insert_list_sorted({i, values[i]});
        }
        auto end = std::chrono::high_resolution_clock::now();
        auto insert_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        printf("insert_list_sorted %d elements took %lld microseconds\n", TEST_SIZE, insert_time.count());

        // 验证排序正确性
        std::vector<int> sorted_values;
        for (auto it = perfMap.list_begin(); it != perfMap.list_end(); ++it)
        {
            sorted_values.push_back(it->second);
        }
        EXPECT_TRUE(std::is_sorted(sorted_values.begin(), sorted_values.end()));
        EXPECT_EQ(perfMap.size(), TEST_SIZE);

        // 测试move_to_list_sorted性能
        start = std::chrono::high_resolution_clock::now();
        for (int i = 0; i < 20; ++i) // 移动20个元素
        {
            auto it = perfMap.find(i);
            if (it != perfMap.end())
            {
                perfMap.move_to_list_sorted(it);
            }
        }
        end = std::chrono::high_resolution_clock::now();
        auto move_time = std::chrono::duration_cast<std::chrono::microseconds>(end - start);

        printf("move_to_list_sorted 20 elements took %lld microseconds\n", move_time.count());

        // 再次验证排序正确性
        sorted_values.clear();
        for (auto it = perfMap.list_begin(); it != perfMap.list_end(); ++it)
        {
            sorted_values.push_back(it->second);
        }
        EXPECT_TRUE(std::is_sorted(sorted_values.begin(), sorted_values.end()));
    }

    printf("EdgeCasesAndPerformance test passed\n");
}

